package com.yourenbang.lingyun.transaction.util.fusuilinggong;

import com.alibaba.fastjson.JSON;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.*;

public class FuSuiLingGongUtil {
    /**
     * 请求成功的状态码
     */
    public static Integer SUCCESS_CODE = 0;
    /**
     * 自由职业者认证回调
     */
    public static String MSG_METHOD_PEOPLE_STATUS_CALLBACK = "people_status_callback";
    /**
     * 用工计划支付状态变更回调
     */
    public static String MSG_METHOD_PLAN_STATUS_CALLBACK = "plan_status_callback";

    /**
     * 响应成功
     */
    public static String RESPONSE_SUCCESS = "success";
    /**
     * 响应失败
     */
    public static String RESPONSE_ERROR = "error";

    private final static String APP_KEY = "804731659334575";
    private final static String APP_SECRET = "u697uxqxr954x8hkoFjY0WJNzMMnGUsNDRZU4IOTR4w=";

    public static void main(String[] args) {
        Map<String, String> paramsMap = new HashMap<>();
        paramsMap.put("idCard", "42032219600118042X");
        paramsMap.put("taskNo", "1554711117613686786");
        paramsMap.put("mobile", "13211118888");
        paramsMap.put("userName", "张三");
        System.out.println("===========================================请求开始============================================");
        String json = JSON.toJSONString(paramsMap);
        System.out.println("业务参数: " + json);
        // 毫秒
        String currentTimeMillis = "1660707102829";
        // 长度最大32位
        String nonce = "a57b45a9ac374b23bac50922c8394a74";
        // 固定参数
        Map<String, String> param = new HashMap<String, String>();
        param.put("appId", APP_KEY);
        param.put("nonce", nonce);
        param.put("timestamp", currentTimeMillis);
        param.put("bizContent", json);
        String sign = null;
        String sortParams = sortParams(param);
        System.out.println("排序字段:" + sortParams);
        String sb = splice(APP_SECRET, sortParams);
        System.out.println("加签名字符串排序字段 :" + sb);
        try {
            sign = sign(sb, currentTimeMillis, APP_SECRET);
        } catch (Exception e) {
            e.printStackTrace();
        }
        param.put("sign", sign);
        System.out.println("签名 : " + sign);
        String postJson = JSON.toJSONString(param);
        System.out.println("请求参数: " + postJson);
    }


    /**
     * 将map排序为字符串
     *
     * @param parameters
     * @return
     */
    public static String sortParams(Map<String, String> parameters) {

        if (parameters.isEmpty()) {
            return null;
        }
        List<String> removeKeys = new ArrayList<>();
        for (Map.Entry<String, String> entry : parameters.entrySet()) {
            if (isBlank(entry.getValue())) {
                removeKeys.add(entry.getKey());
            }
        }

        for (String key : removeKeys) {
            parameters.remove(key);
        }
        StringBuilder stringBuilder = new StringBuilder();
        SortedMap<String, String> paramMap = new TreeMap<>(parameters);
        int index = 0;
        for (Map.Entry<String, String> entry : paramMap.entrySet()) {
            stringBuilder.append(entry.getKey()).append("=").append(entry.getValue());
            index++;
            if (index != parameters.size()) {
                stringBuilder.append("&");
            }
        }
        return stringBuilder.toString();
    }


    public static byte[] hmac256(byte[] key, String msg) throws Exception {
        Mac mac = Mac.getInstance("HmacSHA256");
        SecretKeySpec secretKeySpec = new SecretKeySpec(key, mac.getAlgorithm());
        mac.init(secretKeySpec);
        return mac.doFinal(msg.getBytes(StandardCharsets.UTF_8));
    }

    public static String sha256Hex(String s) throws Exception {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        byte[] d = md.digest(s.getBytes(StandardCharsets.UTF_8));
        return DatatypeConverter.printHexBinary(d).toLowerCase();
    }

    /**
     * 拼接appSecret和
     *
     * @param appSecret
     * @param content   sortParams
     * @return
     */
    public static String splice(String appSecret, String content) {

        if (appSecret == null) {
            return content;
        }
        if (appSecret.length() < 10) {
            return "";
        }

        // 截取前5位和后5位
        String front = appSecret.substring(0, 5);
        String back = appSecret.substring(appSecret.length() - 5);

        return front + content + back;
    }


    /**
     * @param sortParam 排序map后得到的字符串
     * @param timestamp 时间戳
     * @param appSecret 应用秘钥
     * @return 签名值
     * @throws Exception 异常
     */
    public static String sign(String sortParam,
                              String timestamp,
                              String appSecret) throws Exception {
        //将排序后字符串转为sha256Hex
        String signText = sha256Hex(sortParam);
        System.out.println(signText);
        //计算签名
        byte[] secretSigning = hmac256((appSecret).getBytes(StandardCharsets.UTF_8), timestamp);
        //计算后得到签名
        return DatatypeConverter.printHexBinary(hmac256(secretSigning, signText)).toLowerCase();
    }

    public static boolean isBlank(CharSequence str) {
        int length;

        if ((str == null) || ((length = str.length()) == 0)) {
            return true;
        }

        for (int i = 0; i < length; i++) {
            // 只要有一个非空字符即为非空字符串
            if (!isBlankChar(str.charAt(i))) {
                return false;
            }
        }

        return true;
    }

    public static boolean isBlankChar(int c) {
        return Character.isWhitespace(c)
                || Character.isSpaceChar(c)
                || c == '\ufeff'
                || c == '\u202a'
                || c == '\u0000';
    }
}
